//
// Unihan Input Method
//
// Copyright © 2002-2007 Sun Wah Linux Ltd.
//
//
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 2.1 of the
// License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
// USA
//
// $Id: us_keyboard.c 757 2007-05-10 08:19:31Z roger $
//

/*
 * same to punc_keyboard.c
 */

#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif /* HAVE_CONFIG_H */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libintl.h>

#include <gtk/gtk.h>
#include <gdk/gdkx.h>
#include <gdk-pixbuf/gdk-pixdata.h>

#include <gconf/gconf-client.h>

#include <X11/X.h>
#include <X11/Xatom.h>
#include <X11/Xproto.h>

#include <xaux_common.h>
#include <xaux_ext_common.h>
#include <unihan_xaux.h>

#include "unihan-gconf.h"
#include "punc_keyboard.h"
#include "us_keyboard.h"
#include "key_us_images.h"
#include "us.h"
#include "global.h"

static KeyboardKey us_keys[] = {
	/* 1st row */
	{ &UNIHAN_us_key_wave,	0,	0,	'`' },
	{ &UNIHAN_us_key_1,		22,	0,	'1' },
	{ &UNIHAN_us_key_2,		44,	0,	'2' },
	{ &UNIHAN_us_key_3,		66,	0,	'3' },
	{ &UNIHAN_us_key_4,		88,	0,	'4' },
	{ &UNIHAN_us_key_5,		110,	0,	'5' },
	{ &UNIHAN_us_key_6,		132,	0,	'6' },
	{ &UNIHAN_us_key_7,		154,	0,	'7' },
	{ &UNIHAN_us_key_8,		176,	0,	'8' },
	{ &UNIHAN_us_key_9,		198,	0,	'9' },
	{ &UNIHAN_us_key_0,		220,	0,	'0' },
	{ &UNIHAN_us_key_minus,		242,	0,	'-' },
	{ &UNIHAN_us_key_equal,		264,	0,	'=' },
	{ &UNIHAN_us_key_backslash,	286,	0,	'\\'},
	{ &UNIHAN_us_key_backspace,	308,	0,	'\b'},
	/* 2nd row */
	{ &UNIHAN_us_key_tab,		0,	24,	'\t' },
	{ &UNIHAN_us_key_q,		33,	24,	'q' },
	{ &UNIHAN_us_key_w,		55,	24,	'w' },
	{ &UNIHAN_us_key_e,		77,	24,	'e' },
	{ &UNIHAN_us_key_r,		99,	24,	'r' },
	{ &UNIHAN_us_key_t,		121,	24,	't' },
	{ &UNIHAN_us_key_y,		143,	24,	'y' },
	{ &UNIHAN_us_key_u,		165,	24,	'u' },
	{ &UNIHAN_us_key_i,		187,	24,	'i' },
	{ &UNIHAN_us_key_o,		209,	24,	'o' },
	{ &UNIHAN_us_key_p,		231,	24,	'p' },
	{ &UNIHAN_us_key_openbracket,	253,	24,	'[' },
	{ &UNIHAN_us_key_closebracket,	275,	24,	']' },
	{ &UNIHAN_us_key_enter1,	297,	24,	'\n' },
	/* 3rd row */
	{ &UNIHAN_us_key_caps,		0,	48,	'\x1c' },
	{ &UNIHAN_us_key_caps2,		0,	48, '\x1c' },
	{ &UNIHAN_us_key_a,		44,	48,	'a' },
	{ &UNIHAN_us_key_s,		66,	48,	's' },
	{ &UNIHAN_us_key_d,		88,	48,	'd' },
	{ &UNIHAN_us_key_f,		110,	48,	'f' },
	{ &UNIHAN_us_key_g,		132,	48,	'g' },
	{ &UNIHAN_us_key_h,		154,	48,	'h' },
	{ &UNIHAN_us_key_j,		176,	48,	'j' },
	{ &UNIHAN_us_key_k,		198,	48,	'k' },
	{ &UNIHAN_us_key_l,		220,	48,	'l' },
	{ &UNIHAN_us_key_semicolon,	242,	48,	';' },
	{ &UNIHAN_us_key_quotes,	264,	48,	'\'' },
	{ &UNIHAN_us_key_enter2,	286,	48,	'\n' },
	{ &UNIHAN_us_key_enter3,	297,	48,	'\n' },
	/* 4th row */
	{ &UNIHAN_us_key_left_shift,	0,	72,	'\x1d' },
	{ &UNIHAN_us_key_left_shift2,	0,	72, '\x1d' },
	{ &UNIHAN_us_key_z,		55,	72,	'z' },
	{ &UNIHAN_us_key_x,		77,	72,	'x' },
	{ &UNIHAN_us_key_c,		99,	72,	'c' },
	{ &UNIHAN_us_key_v,		121,	72,	'v' },
	{ &UNIHAN_us_key_b,		143,	72,	'b' },
	{ &UNIHAN_us_key_n,		165,	72,	'n' },
	{ &UNIHAN_us_key_m,		187,	72,	'm' },
	{ &UNIHAN_us_key_comma,		209,	72,	',' },
	{ &UNIHAN_us_key_period,	231,	72,	'.' },
	{ &UNIHAN_us_key_slash,		253,	72,	'/' },
	{ &UNIHAN_us_key_right_shift,	275,	72,	'\x1d' },
	{ &UNIHAN_us_key_right_shift2,	275,	72, '\x1d' },
	/* 5th row */
	{ &UNIHAN_us_key_left_ctrl,		0,	96,	'\0' },
	{ &UNIHAN_us_key_esc,		33,	96,	'\x1b' },
	{ &UNIHAN_us_key_alt,		66,	96,	'\0' },
	{ &UNIHAN_us_key_space,		99, 96,	' ' },
	{ &UNIHAN_us_key_alt,		231,96, '\0' },
	{ &UNIHAN_us_key_right_ctrl,		297,96,	'\0' },

	{ NULL,				0,	0,	'\0' }
};

static GtkWidget *keyboard_window = NULL;
static GtkWidget *caps_image = NULL;
static GtkWidget *caps2_image = NULL;
static GtkWidget *left_shift_image = NULL;
static GtkWidget *left_shift2_image = NULL;
static GtkWidget *right_shift_image = NULL;
static GtkWidget *right_shift2_image = NULL;

static gboolean shift_key_pressed = FALSE;
static gboolean caps_lock_pressed = FALSE;

static gboolean
us_key_clicked(GtkWidget *w, GdkEventButton *e, char *ch)
{
	int int_values[3];
	int_values[0] = UNIHAN_ENGINE_US_KEYBOARD;
	char *str_values[1];
	static char char_temp;
	char *ptr_temp;

	if (e->button != 1)
	{
		return FALSE;
	}

	ptr_temp = find_key((int)*ch);

	if (ptr_temp) {
		char_temp = *ptr_temp;
	} else {
		return FALSE;
	}

	if (shift_key_pressed) {
		switch (char_temp) {
			case '`':
				char_temp = '~';
				break;
			case '1':
				char_temp = '!';
				break;
			case '2':
				char_temp = '@';
				break;
			case '3':
				char_temp = '#';
				break;
			case '4':
				char_temp = '$';
				break;
			case '5':
				char_temp = '%';
				break;
			case '6':
				char_temp = '^';
				break;
			case '7':
				char_temp = '&';
				break;
			case '8':
				char_temp = '*';
				break;
			case '9':
				char_temp = '(';
				break;
			case '0':
				char_temp = ')';
				break;
			case '-':
				char_temp = '_';
				break;
			case '=':
				char_temp = '+';
				break;
			case '\\':
				char_temp = '|';
				break;
			case '[':
				char_temp = '{';
				break;
			case ']':
				char_temp = '}';
				break;
			case ';':
				char_temp = ':';
				break;
			case '\'':
				char_temp = '\"';
				break;
			case ',':
				char_temp = '<';
				break;
			case '.':
				char_temp = '>';
				break;
			case '/':
				char_temp = '?';
				break;
			default:
				break;
		}
	}

	if ( (char_temp >= 'a') && (char_temp <= 'z') && (caps_lock_pressed ^ shift_key_pressed) ) 
		char_temp -= 0x20;

	if (char_temp == '\x1c') {
		caps_lock_pressed = !caps_lock_pressed;
		if (caps_lock_pressed) {
			gtk_widget_hide(caps_image);
			gtk_widget_show(caps2_image);
		} else {
			gtk_widget_hide(caps2_image);
			gtk_widget_show(caps_image);
		}
		//gtk_widget_show_all(w);
		int_values[0] = UNIHAN_ENGINE_US_KEYBOARD_SET_STATE;
		int_values[1] = (caps_lock_pressed ? 1 : 0);
		int_values[2] = (shift_key_pressed ? 1 : 0);
		send_to_engine(3, int_values, 0, NULL);
		return TRUE;
	}

	if (char_temp == '\x1d') {
		shift_key_pressed = !shift_key_pressed;
		if (shift_key_pressed) {
			gtk_widget_hide(left_shift_image);
			gtk_widget_hide(right_shift_image);
			gtk_widget_show(left_shift2_image);
			gtk_widget_show(right_shift2_image);
		} else {
			gtk_widget_hide(left_shift2_image);
			gtk_widget_hide(right_shift2_image);
			gtk_widget_show(left_shift_image);
			gtk_widget_show(right_shift_image);
		}
		int_values[0] = UNIHAN_ENGINE_US_KEYBOARD_SET_STATE;
		int_values[1] = (caps_lock_pressed ? 1 : 0);
		int_values[2] = (shift_key_pressed ? 1 : 0);
		send_to_engine(3, int_values, 0, NULL);
		return TRUE;
	}
	else {
		shift_key_pressed = FALSE;
		gtk_widget_hide(left_shift2_image);
		gtk_widget_hide(right_shift2_image);
		gtk_widget_show(left_shift_image);
		gtk_widget_show(right_shift_image);
	}

	str_values[0] = &char_temp;
	send_to_engine(1, int_values, 1, str_values);

		//int_values[0] = UNIHAN_ENGINE_TOGGLE_US;
		//send_to_engine(1, int_values, 0, NULL);

		//hide_us_keyboard();
	return TRUE;
}

static void
draw_us_keyboard(GtkWidget * key_images[], int NO_OF_KEYS)
{
	GtkWidget *keyboard_layout;
	GtkWidget *event_boxes[NO_OF_KEYS];
	int i;

	keyboard_layout = gtk_layout_new(NULL, NULL);
	keyboard_window = gtk_window_new(GTK_WINDOW_POPUP);

	gtk_container_add(GTK_CONTAINER(keyboard_window), keyboard_layout);

	for(i=0; i<NO_OF_KEYS; i++) {
		GdkPixbuf *tmp_pixbuf;

		tmp_pixbuf = gdk_pixbuf_from_pixdata(us_keys[i].image,
				FALSE, NULL);
		key_images[i] = gtk_image_new_from_pixbuf(tmp_pixbuf);
		event_boxes[i] = gtk_event_box_new();

		gtk_container_add(GTK_CONTAINER(event_boxes[i]), key_images[i]);

		/*
		if ( i == 30 || i == 45 || i == 57 ) {
			continue;
		}
		*/
		gtk_layout_put((GtkLayout *)keyboard_layout,
				event_boxes[i],
				us_keys[i].x + KEYBOARD_BORDER,
				us_keys[i].y + KEYBOARD_BORDER);
		gtk_widget_set_events(key_images[i], GDK_BUTTON_PRESS_MASK);
		//g_signal_connect( G_OBJECT(event_boxes[i]),
		//		"button_release_event",
		//		G_CALLBACK(us_key_clicked),
		//		&(us_keys[i].ch) );

		g_signal_connect(G_OBJECT(event_boxes[i]),
						  "button_press_event",
						  G_CALLBACK(us_key_clicked),
						  &(us_keys[i].ch) );

		g_signal_connect(G_OBJECT(keyboard_layout),
						  "expose_event",
						  G_CALLBACK(keyboard_window_expose),
						  NULL);
	}

	g_signal_connect(G_OBJECT(keyboard_layout),
					 "button_press_event",
					 G_CALLBACK(move_keyboard_window),
					 NULL);
	caps_image = key_images[29];
	caps2_image = key_images[30];
	left_shift_image = key_images[44];
	left_shift2_image = key_images[45];
	right_shift_image = key_images[56];
	right_shift2_image = key_images[57];

	/*
	GdkPixbuf *tmp_pixbuf = gdk_pixbuf_from_pixdata( &UNIHAN_us_key_caps1, FALSE, NULL);
	GtkWidget *tmp_image = gtk_image_new_from_pixbuf(tmp_pixbuf);
	char ch='\x1c';
	gtk_container_add( GTK_CONTAINER(caps_event_box), tmp_image );
	gtk_layout_put( (GtkLayout *)keyboard_layout, caps_event_box,
					0 + KEYBOARD_BORDER, 48 + KEYBOARD_BORDER );
	gtk_widget_set_events(tmp_image, GDK_BUTTON_PRESS_MASK);
	g_signal_connect( G_OBJECT(caps_event_box), 
					  "button_press_event",
					  G_CALLBACK(us_key_clicked),
					  &ch );

	GdkPixbuf *tmp_pixbuf = gdk_pixbuf_from_pixdata( &UNIHAN_us_key_left_shift, FALSE, NULL);
	GtkWidget *tmp_image = gtk_image_new_from_pixbuf(tmp_pixbuf);
	char ch='\x1d';
	gtk_container_add( GTK_CONTAINER(left_shift_event_box), tmp_image );
	gtk_layout_put( (GtkLayout *)keyboard_layout, left_shift_event_box,
					0 + KEYBOARD_BORDER, 72 + KEYBOARD_BORDER );
	gtk_widget_set_events(tmp_image, GDK_BUTTON_PRESS_MASK);
	g_signal_connect( G_OBJECT(left_shift_event_box), 
					  "button_press_event",
					  G_CALLBACK(us_key_clicked),
					  &ch );

	GdkPixbuf *tmp_pixbuf = gdk_pixbuf_from_pixdata( &UNIHAN_us_key_right_shift, FALSE, NULL);
	GtkWidget *tmp_image = gtk_image_new_from_pixbuf(tmp_pixbuf);
	char ch='\x1d';
	gtk_container_add( GTK_CONTAINER(right_shift_event_box), tmp_image );
	gtk_layout_put( (GtkLayout *)keyboard_layout, right_shift_event_box,
					275 + KEYBOARD_BORDER, 72 + KEYBOARD_BORDER );
	gtk_widget_set_events(tmp_image, GDK_BUTTON_PRESS_MASK);
	g_signal_connect( G_OBJECT(right_shift_event_box), 
					  "button_press_event",
					  G_CALLBACK(us_key_clicked),
					  &ch );
					  */
}

void
show_us_keyboard(void)
{
	int screen_w, screen_h;
	int i;
	static Bool cursor_already_set = FALSE;
	static int NO_OF_KEYS = (sizeof(us_keys)) / (sizeof(KeyboardKey)) - 1;
	GtkWidget *key_images[NO_OF_KEYS];

	if (!keyboard_window)
		draw_us_keyboard(key_images, NO_OF_KEYS);

	screen_w = gdk_screen_width();
	screen_h = gdk_screen_height();
	gtk_window_set_gravity(GTK_WINDOW(keyboard_window),
			GDK_GRAVITY_SOUTH_EAST);

	gtk_window_set_default_size(GTK_WINDOW(keyboard_window),
			KEYBOARD_FULL_WIDTH,
			KEYBOARD_FULL_HEIGHT);
	gtk_window_move(GTK_WINDOW(keyboard_window),
			screen_w - 20 - KEYBOARD_FULL_WIDTH,
			screen_h - 20 - KEYBOARD_FULL_HEIGHT);
	gtk_widget_show_all(keyboard_window);
	gtk_window_present(GTK_WINDOW(keyboard_window));

	if (!cursor_already_set) {
		for (i=0; i<NO_OF_KEYS; i++) {
			gdk_window_set_cursor(key_images[i]->window,
					gdk_cursor_new(GDK_CENTER_PTR));
		}
		cursor_already_set = TRUE;
	}
}

void
hide_us_keyboard(void)
{
	if (keyboard_window) {
		//gtk_widget_destroy(keyboard_window);
		//keyboard_window = NULL;
		gtk_widget_hide(keyboard_window);
	}
}

void set_us_keyboard_state(int caps_state, int shift_state)
{
	caps_lock_pressed = caps_state;
	if (caps_lock_pressed) {
		gtk_widget_hide(caps_image);
		gtk_widget_show(caps2_image);
	} else {
		gtk_widget_hide(caps2_image);
		gtk_widget_show(caps_image);
	}
	shift_key_pressed = shift_state;
	if (shift_key_pressed) {
		gtk_widget_hide(left_shift_image);
		gtk_widget_hide(right_shift_image);
		gtk_widget_show(left_shift2_image);
		gtk_widget_show(right_shift2_image);
	} else {
		gtk_widget_hide(left_shift2_image);
		gtk_widget_hide(right_shift2_image);
		gtk_widget_show(left_shift_image);
		gtk_widget_show(right_shift_image);
	}
}


// vi:ts=4:nowrap:cin:expandtab
